﻿using Polly;
using Polly.Retry;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CoreService.Core
{
    /// <summary>
    /// Redis 助手
    /// </summary>
    public static class RedisHelper
    {
        //连接字符串
        private static readonly string ConnectionString = ConfigurationManager.ConnectionStrings["Redis"].ConnectionString;
        //redis出现异常重试次数
        private static readonly int RetryCount = Convert.ToInt32(ConfigurationManager.AppSettings["RetryCount"]);
        //redis连接对象
        private static IConnectionMultiplexer _connMultiplexer;
        //数据库
        private static IDatabase _db;
        //重试对象
        private static RetryPolicy retryPolicy = null;

        //静态构造
        static RedisHelper()
        {
            InitRetry();
            _connMultiplexer = ConnectionMultiplexer.Connect(ConnectionString);
            _db = _connMultiplexer.GetDatabase(CommonHelper.RedisDB);
            Console.WriteLine("Initialize Redis Connetion Complete....");
        }

        //初始化重试机制
        private static void InitRetry()
        {
            retryPolicy = Policy.Handle<Exception>().Retry(RetryCount, (ex, count) =>
            {
                string threadID = Thread.CurrentThread.ManagedThreadId.ToString();
                string info = string.Format("线程ID：{0}重试次数：{1},异常信息：{2}", threadID, count, ex.Message);
                Console.WriteLine(info);
                LogHelper.Waring(info);
                Thread.Sleep(1000);
            });
        }

        //得到一个事物
        public static ITransaction GetTransaction()
        {
            return retryPolicy.Execute(() =>
            {
                return _db.CreateTransaction();
            });
        }

        //执行命令
        public static string Execute(string cmd, params object[] args)
        {
            return retryPolicy.Execute(() =>
            {
                RedisResult rr = _db.Execute(cmd, args);
                return rr.IsNull ? null : rr.ToString();
            });
        }

        #region String 操作

        /// <summary>
        /// 获取字符串
        /// </summary>
        /// <param name="redisKey">获取指定键值</param>
        /// <returns></returns>
        public static string StringGet(string redisKey)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.StringGet(redisKey);
            });
        }

        /// <summary>
        /// 自增键,不存在则为0
        /// </summary>
        /// <param name="redisKey">自增键</param>
        /// <returns></returns>
        public static long StringIncrement(string redisKey)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.StringIncrement(redisKey);
            });
        }

        /// <summary>
        /// 设置key并保存字符串。如果key已存在，则覆盖值。
        /// </summary>
        /// <param name="redisKey">键</param>
        /// <param name="redisValue">值</param>
        /// <param name="expiry">超时时间</param>
        /// <returns></returns>
        public static bool StringSet(string redisKey, string redisValue, TimeSpan? expiry = null)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.StringSet(redisKey, redisValue, expiry);
            });
        }

        /// <summary>
        /// 保存List类型键值集合
        /// </summary>
        /// <param name="keyValueList">键值对集合</param>
        /// <returns></returns>
        public static bool StringSet(IEnumerable<KeyValuePair<string, string>> keyValueList)
        {
            return retryPolicy.Execute(() =>
            {
                var keyValueArry = keyValueList.Select(x => new KeyValuePair<RedisKey, RedisValue>(x.Key, x.Value)).ToArray();
                return _db.StringSet(keyValueArry);
            });
        }

        /// <summary>
        /// 获取字符串（异步操作）
        /// </summary>
        /// <param name="redisKey">键</param>
        /// <returns></returns>
        public static async Task<string> StringGetAsync(string redisKey)
        {
            return await retryPolicy.Execute(() =>
            {
                return _db.StringGetAsync(redisKey);
            });
        }

        /// <summary>
        /// 设置key并保存字符串。如果key已存在，则覆盖值。（异步操作）
        /// </summary>
        /// <param name="redisKey">键</param>
        /// <param name="redisValue">值</param>
        /// <param name="expiry">超时时间</param>
        /// <returns></returns>
        public static async Task<bool> StringSetAsync(string redisKey, string redisValue, TimeSpan? expiry = null)
        {
            return await retryPolicy.Execute(() =>
            {
                return _db.StringSetAsync(redisKey, redisValue, expiry);
            });
        }

        /// <summary>
        /// 保存一组字符串值
        /// </summary>
        /// <param name="keyValuePairs">键值对集合</param>
        /// <returns></returns>
        public static async Task<bool> StringSetAsync(IEnumerable<KeyValuePair<string, string>> keyValueList)
        {
            return await retryPolicy.Execute(() =>
            {
                var pairs = keyValueList.Select(x => new KeyValuePair<RedisKey, RedisValue>(x.Key, x.Value)).ToArray();
                return _db.StringSetAsync(pairs);
            });
        }

        #endregion

        #region Hash 操作

        //hash key field value field1 value1

        /// <summary>
        /// 根据键和字段返回值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashField"></param>
        /// <returns></returns>
        public static string HashGet(string redisKey, string hashField)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.HashGet(redisKey, hashField);
            });
        }

        /// <summary>
        /// 根据键和字段集合返回值集合
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashFields"></param>
        /// <returns></returns>
        public static List<string> HashGet(string redisKey, IEnumerable<string> hashFields)
        {
            return retryPolicy.Execute(() =>
            {
                var fields = hashFields.Select(x => (RedisValue)x).ToArray(); ;
                return _db.HashGet(redisKey, fields).Select(x => x.ToString()).ToList();
            });
        }

        /// <summary>
        /// 根据键返回所有字段集合
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static List<string> HashKeys(string redisKey)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.HashKeys(redisKey).Select(x => x.ToString()).ToList();
            });
        }

        /// <summary>
        /// 根据键返回所有值集合
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static List<string> HashValues(string redisKey)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.HashValues(redisKey).Select(x => x.ToString()).ToList();
            });
        }

        /// <summary>
        /// 判断字段是否在此hash中
        /// </summary>
        /// <param name="redisKey">键</param>
        /// <param name="hashField"></param>
        /// <returns></returns>
        public static bool HashExists(string redisKey, string hashField)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.HashExists(redisKey, hashField);
            });
        }

        /// <summary>
        /// 移除hash中的字段，如果没有此字段返回0
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashField"></param>
        /// <returns></returns>
        public static bool HashDelete(string redisKey, string hashField)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.HashDelete(redisKey, hashField);
            });
        }

        /// <summary>
        /// 移除hash中的字段集合
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashFields"></param>
        /// <returns></returns>
        public static long HashDelete(string redisKey, IEnumerable<string> hashFields)
        {
            return retryPolicy.Execute(() =>
            {
                var fields = hashFields.Select(x => (RedisValue)x).ToArray();
                return _db.HashDelete(redisKey, fields);
            });
        }

        /// <summary>
        /// 设置hash中字段和值，如果字段不存在则创建，存在则覆盖
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashField"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool HashSet(string redisKey, string hashField, string value)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.HashSet(redisKey, hashField, value);
            });
        }

        /// <summary>
        /// 设置hash中字段值集合，如果字段不存在则创建，存在则覆盖
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashFields"></param>
        public static void HashSet(string redisKey, IEnumerable<KeyValuePair<string, string>> hashFields)
        {
            retryPolicy.Execute(() =>
            {
                var entries = hashFields.Select(x => new HashEntry(x.Key, x.Value)).ToArray();
                _db.HashSet(redisKey, entries);
            });
        }

        /// <summary>
        /// 判断该字段是否存在hash中(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashField"></param>
        /// <returns></returns>
        public static async Task<bool> HashExistsAsync(string redisKey, string hashField)
        {
            return await retryPolicy.Execute(() =>
            {
                return _db.HashExistsAsync(redisKey, hashField);
            });
        }

        /// <summary>
        /// 从hash中移除指定字段(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashField"></param>
        /// <returns></returns>
        public static async Task<bool> HashDeleteAsync(string redisKey, string hashField)
        {
            return await retryPolicy.Execute(() =>
            {
                return _db.HashDeleteAsync(redisKey, hashField);
            });
        }

        /// <summary>
        /// 从hash中移除指定字段集合(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashFields"></param>
        /// <returns></returns>
        public static async Task<long> HashDeleteAsync(string redisKey, IEnumerable<string> hashFields)
        {
            return await retryPolicy.Execute(() =>
            {
                var fields = hashFields.Select(x => (RedisValue)x).ToArray();
                return _db.HashDeleteAsync(redisKey, fields);
            });
        }

        /// <summary>
        /// 在hash设定字段值(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashField"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static async Task<bool> HashSetAsync(string redisKey, string hashField, string value)
        {
            return await retryPolicy.Execute(() =>
            {
                return _db.HashSetAsync(redisKey, hashField, value);
            });
        }

        /// <summary>
        /// 在hash中设定字段值集合(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashFields"></param>
        public static async Task HashSetAsync(string redisKey, IEnumerable<KeyValuePair<string, string>> hashFields)
        {
            retryPolicy.Execute(() =>
            {
                var entries = hashFields.Select(x => new HashEntry(x.Key, x.Value)).ToArray();
                _db.HashSetAsync(redisKey, entries);
            });
        }

        /// <summary>
        /// 在hash中获取值(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashField"></param>
        /// <returns></returns>
        public static async Task<string> HashGetAsync(string redisKey, string hashField)
        {
            return await retryPolicy.Execute(() =>
            {
                return _db.HashGetAsync(redisKey, hashField);
            });
        }

        /// <summary>
        /// 根据字段集合返回值集合(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashFields"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static async Task<List<string>> HashGetAsync(string redisKey, IEnumerable<string> hashFields)
        {
            return (await retryPolicy.Execute(() =>
            {
                var fields = hashFields.Select(x => (RedisValue)x).ToArray();
                return _db.HashGetAsync(redisKey, fields);
            })).Select(x => x.ToString()).ToList();
        }

        /// <summary>
        /// 从hash返回所有的字段(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static async Task<List<string>> HashKeysAsync(string redisKey)
        {
            return (await retryPolicy.Execute(() =>
            {
                return _db.HashKeysAsync(redisKey);
            })).Select(x => x.ToString()).ToList();
        }

        /// <summary>
        /// 返回hash中的所有值(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static async Task<List<string>> HashValuesAsync(string redisKey)
        {
            return (await retryPolicy.Execute(() =>
            {
                return _db.HashValuesAsync(redisKey);
            })).Select(x => x.ToString()).ToList();
        }

        #endregion

        #region List 操作

        /// <summary>
        /// 移除并返回存储在该键列表的第一个元素
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static string ListLeftPop(string redisKey)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.ListLeftPop(redisKey);
            });
        }

        /// <summary>
        /// 移除并返回存储在该键列表的最后一个元素
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static string ListRightPop(string redisKey)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.ListRightPop(redisKey);
            });
        }

        /// <summary>
        /// 移除列表指定键上与该值相同的元素
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
        public static long ListRemove(string redisKey, string redisValue)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.ListRemove(redisKey, redisValue);
            });
        }

        /// <summary>
        /// 在列表尾部插入值。如果键不存在，先创建再插入值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
        public static long ListRightPush(string redisKey, string redisValue)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.ListRightPush(redisKey, redisValue);
            });
        }

        /// <summary>
        /// 在列表头部插入值。如果键不存在，先创建再插入值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
        public static long ListLeftPush(string redisKey, string redisValue)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.ListLeftPush(redisKey, redisValue);
            });
        }

        /// <summary>
        /// 返回列表上该键的长度，如果不存在，返回 0
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static long ListLength(string redisKey)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.ListLength(redisKey);
            });
        }

        /// <summary>
        /// 返回在该列表上键所对应的元素
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <returns></returns>
        public static List<string> ListRange(string redisKey, long start = 0L, long stop = -1L)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.ListRange(redisKey, start, stop).Select(x => x.ToString()).ToList();
            });
        }

        /// <summary>
        /// 移除并返回存储在该键列表的第一个元素(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static async Task<string> ListLeftPopAsync(string redisKey)
        {
            return await retryPolicy.Execute(() =>
            {
                return _db.ListLeftPopAsync(redisKey);
            });
        }

        /// <summary>
        /// 移除并返回存储在该键列表的最后一个元素(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static async Task<string> ListRightPopAsync(string redisKey)
        {
            return await retryPolicy.Execute(() =>
            {
                return _db.ListRightPopAsync(redisKey);
            });
        }

        /// <summary>
        /// 移除列表指定键上与该值相同的元素(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
        public static async Task<long> ListRemoveAsync(string redisKey, string redisValue)
        {
            return await retryPolicy.Execute(() =>
            {
                return _db.ListRemoveAsync(redisKey, redisValue);
            });
        }

        /// <summary>
        /// 在列表尾部插入值。如果键不存在，先创建再插入值(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
        public static async Task<long> ListRightPushAsync(string redisKey, string redisValue)
        {
            return await retryPolicy.Execute(() =>
            {
                return _db.ListRightPushAsync(redisKey, redisValue);
            });
        }

        /// <summary>
        /// 在列表头部插入值。如果键不存在，先创建再插入值(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
        public static async Task<long> ListLeftPushAsync(string redisKey, string redisValue)
        {
            return await retryPolicy.Execute(() =>
            {
                return _db.ListLeftPushAsync(redisKey, redisValue);
            });
        }

        /// <summary>
        /// 返回列表上该键的长度，如果不存在，返回0(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static async Task<long> ListLengthAsync(string redisKey)
        {
            return await retryPolicy.Execute(() =>
            {
                return _db.ListLengthAsync(redisKey);
            });
        }

        /// <summary>
        /// 返回在该列表上键所对应的元素集合(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <returns></returns>
        public static async Task<List<string>> ListRangeAsync(string redisKey, long start = 0L, long stop = -1L)
        {
            return (await retryPolicy.Execute(() =>
            {
                return _db.ListRangeAsync(redisKey, start, stop);
            })).Select(x => x.ToString()).ToList();
        }

        #endregion

        #region Set 无序集合

        /// <summary>
        /// 添加成员到集合
        /// </summary>
        /// <param name="redisKey">键</param>
        /// <param name="member">成员</param>
        /// <returns></returns>
        public static bool SetAdd(string redisKey, string member)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.SetAdd(redisKey, member);
            });
        }

        /// <summary>
        /// 添加成员到集合(异步操作)
        /// </summary>
        /// <param name="redisKey">键</param>
        /// <param name="member">成员</param>
        /// <returns></returns>
        public static async Task<bool> SetAddAsync(string redisKey, string member)
        {
            return await retryPolicy.Execute(() =>
            {
                return _db.SetAddAsync(redisKey, member);
            });
        }

        /// <summary>
        /// 返回集合的元素个数
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static long SetLength(string redisKey)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.SetLength(redisKey);
            });
        }

        /// <summary>
        /// 返回集合所有成员
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static List<string> SetMembers(string redisKey)
        {
            return retryPolicy.Execute(() =>
            {
                List<string> _result = _db.SetMembers(redisKey).Select(x => x.ToString()).ToList();
                return _result;
            });
        }

        /// <summary>
        /// 返回集合的元素个数(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static async Task<long> SetLengthAsync(string redisKey)
        {
            return await retryPolicy.Execute(() =>
            {
                return _db.SetLengthAsync(redisKey);
            });
        }

        /// <summary>
        /// 操作两个集合
        /// </summary>
        /// <param name="op">操作类型：Union并集，Intersect交集，Difference差集</param>
        /// <param name="first">集合</param>
        /// <param name="second">集合</param>
        /// <returns></returns>
        public static List<string> SetCombine(SetOperation op, string first, string second)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.SetCombine(op, first, second).Select(x => x.ToString()).ToList();
            });
        }

        /// <summary>
        /// 操作两个集合(异步操作)
        /// </summary>
        /// <param name="op">操作类型：Union并集，Intersect交集，Difference差集</param>
        /// <param name="first">集合</param>
        /// <param name="second">集合</param>
        /// <returns></returns>
        public static async Task<List<string>> SetCombineAsync(SetOperation op, string first, string second)
        {
            return (await retryPolicy.Execute(() =>
            {
                return _db.SetCombineAsync(op, first, second);
            })).Select(x => x.ToString()).ToList();
        }

        /// <summary>
        /// 返回成员是否在集合中
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static bool SetContains(string redisKey, string redisValue)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.SetContains(redisKey, redisValue);
            });
        }

        /// <summary>
        /// 返回成员是否在集合中(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static async Task<bool> SetContainsAsync(string redisKey, string redisValue)
        {
            return await retryPolicy.Execute(() =>
            {
                return _db.SetContainsAsync(redisKey, redisValue);
            });
        }

        /// <summary>
        /// 返回集合所有成员(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static async Task<List<string>> SetMembersAsync(string redisKey)
        {
            return (await retryPolicy.Execute(() =>
            {
                return _db.SetMembersAsync(redisKey);
            })).Select(x => x.ToString()).ToList();
        }

        /// <summary>
        /// 从集合中移除元素
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static bool SetRemove(string redisKey, string redisValue)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.SetRemove(redisKey, redisValue);
            });
        }

        /// <summary>
        /// 从集合中移除元素(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static async Task<bool> SetRemoveAsync(string redisKey, string redisValue)
        {
            return await retryPolicy.Execute(() =>
            {
                return _db.SetRemoveAsync(redisKey, redisValue);
            });
        }

        #endregion

        #region SortedSet 操作

        /// <summary>
        /// 添加成员到有序集合
        /// </summary>
        /// <param name="redisKey">键</param>
        /// <param name="member">成员</param>
        /// <param name="score">编号</param>
        /// <returns></returns>
        public static bool SortedSetAdd(string redisKey, string member, double score)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.SortedSetAdd(redisKey, member, score);
            });
        }

        /// <summary>
        /// 在有序集合中返回指定范围的元素，默认情况下从低到高。
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <param name="order"></param>
        /// <returns></returns>
        public static List<string> SortedSetRangeByRank(string redisKey, long start = 0L, long stop = -1L, Order _order = Order.Ascending)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.SortedSetRangeByRank(redisKey, start, stop, _order).Select(x => x.ToString()).ToList();
            });
        }

        /// <summary>
        /// 返回有序集合的元素个数
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static long SortedSetLength(string redisKey)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.SortedSetLength(redisKey);
            });
        }

        /// <summary>
        /// 移除有序集合的成员
        /// </summary>
        /// <param name="redisKey">键</param>
        /// <param name="memebr">成员</param>
        /// <returns></returns>
        public static bool SortedSetRemove(string redisKey, string memebr)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.SortedSetRemove(redisKey, memebr);
            });
        }

        /// <summary>
        /// 添加成员到有序集合(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="member"></param>
        /// <param name="score"></param>
        /// <returns></returns>
        public static async Task<bool> SortedSetAddAsync(string redisKey, string member, double score)
        {
            return await retryPolicy.Execute(() =>
            {
                return _db.SortedSetAddAsync(redisKey, member, score);
            });
        }

        /// <summary>
        ///  在有序集合中返回指定范围的元素，默认情况下从低到高。(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static async Task<List<string>> SortedSetRangeByRankAsync(string redisKey, long start, long stop, Order order = Order.Ascending)
        {
            return (await retryPolicy.Execute(() =>
            {
                return _db.SortedSetRangeByRankAsync(redisKey, start, stop, order);
            })).Select(x => x.ToString()).ToList();
        }

        /// <summary>
        /// 返回有序集合的元素个数(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static async Task<long> SortedSetLengthAsync(string redisKey)
        {
            return await retryPolicy.Execute(() =>
            {
                return _db.SortedSetLengthAsync(redisKey);
            });
        }

        /// <summary>
        /// 移除有序集合中的成员(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="memebr"></param>
        /// <returns></returns>
        public static async Task<bool> SortedSetRemoveAsync(string redisKey, string memebr)
        {
            return await retryPolicy.Execute(() =>
            {
                return _db.SortedSetRemoveAsync(redisKey, memebr);
            });
        }

        #endregion

        #region key 操作

        /// <summary>
        /// 移除指定 Key
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static bool KeyDelete(string redisKey)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.KeyDelete(redisKey);
            });
        }

        /// <summary>
        /// 移除指定 Key集合
        /// </summary>
        /// <param name="redisKeys"></param>
        /// <returns></returns>
        public static long KeyDelete(IEnumerable<string> redisKeys)
        {
            return retryPolicy.Execute(() =>
            {
                RedisKey[] keys = redisKeys.Select(x => (RedisKey)x).ToArray();
                return _db.KeyDelete(keys);
            });
        }

        /// <summary>
        /// 校验 Key 是否存在
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static bool KeyExists(string redisKey)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.KeyExists(redisKey);
            });
        }

        /// <summary>
        /// 重命名 Key
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisNewKey"></param>
        /// <returns></returns>
        public static bool KeyRename(string redisKey, string redisNewKey)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.KeyRename(redisKey, redisNewKey);
            });
        }

        /// <summary>
        /// 设置 Key 的时间
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="expiry"></param>
        /// <returns></returns>
        public static bool KeyExpire(string redisKey, TimeSpan? expiry)
        {
            return retryPolicy.Execute(() =>
            {
                return _db.KeyExpire(redisKey, expiry);
            });
        }

        /// <summary>
        /// 移除指定 Key(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static async Task<bool> KeyDeleteAsync(string redisKey)
        {
            return await retryPolicy.Execute(() =>
            {
                return _db.KeyDeleteAsync(redisKey);
            });
        }

        /// <summary>
        /// 移除指定 Key集合(异步操作)
        /// </summary>
        /// <param name="redisKeys"></param>
        /// <returns></returns>
        public static async Task<long> KeyDeleteAsync(IEnumerable<string> redisKeys)
        {
            return await retryPolicy.Execute(() =>
            {
                RedisKey[] keys = redisKeys.Select(x => (RedisKey)x).ToArray();
                return _db.KeyDeleteAsync(keys);
            });
        }

        /// <summary>
        /// 校验 Key 是否存在(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public static async Task<bool> KeyExistsAsync(string redisKey)
        {
            return await retryPolicy.Execute(() =>
            {
                return _db.KeyExistsAsync(redisKey);
            });
        }

        /// <summary>
        /// 重命名 Key(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisNewKey"></param>
        /// <returns></returns>
        public static async Task<bool> KeyRenameAsync(string redisKey, string redisNewKey)
        {
            return await retryPolicy.Execute(() =>
            {
                return _db.KeyRenameAsync(redisKey, redisNewKey);
            });
        }

        /// <summary>
        /// 设置 Key 的时间(异步操作)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="expiry"></param>
        /// <returns></returns>
        public static async Task<bool> KeyExpireAsync(string redisKey, TimeSpan? expiry)
        {
            return await retryPolicy.Execute(() =>
            {
                return _db.KeyExpireAsync(redisKey, expiry);
            });
        }

        #endregion

    }
}
